package com.atguigu.tingshu.order.handler;

import com.atguigu.tingshu.order.service.OrderInfoService;
import jakarta.annotation.PostConstruct;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author dxt
 * @create 2025-07-01-19:06
 */
@Component
public class DelayMsgConsumer {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private OrderInfoService orderInfoService;

    /**
     * 初始化方法，用于启动订单状态更新的后台处理线程。
     * 该方法会在Bean初始化完成后自动执行。
     *
     * @throws Exception 如果在初始化过程中发生异常
     */
    @PostConstruct
    public void updateOrderStatus() {
        /**
         * 获取Redisson的阻塞队列实例，用于接收订单状态更新的消息
         * 队列名称为"order:status:queue"
         */
        RBlockingDeque<Object> blockingDeque = redissonClient.getBlockingDeque("order:status:queue");
        /**
         * 创建单例线程池，确保同一时间只有一个任务在执行
         * 提交一个无限循环任务到线程池
         */
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.execute(() -> {
            /**
             * 无限循环任务，持续从阻塞队列中取出消息
             * 每次取出一个消息后，调用orderInfoService更新订单状态
             * 如果发生异常，打印异常堆栈信息
             */
            while (true){
                try {
                    /**
                     * 从阻塞队列中取出消息
                     * 该方法会一直阻塞直到有消息可用
                     */
                    Object message = blockingDeque.take();
                    /**
                     * 调用orderInfoService的updateOrderStatus方法更新订单状态
                     * 将消息转换为字符串格式传递给服务层
                     */
                    orderInfoService.updateOrderStatus(message.toString());
                    }
                /**
                 * 捕获所有异常并打印堆栈跟踪
                 * 实际应用中应考虑更完善的错误处理机制
                 */
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
